<?php
/**
 * gpa_demo Description
 * @package
 * @name Image
 * @filesource image.php
 * @author Meta Sanjaya
 */

class Image {
    private $file;
    private $image;
    private $info;

    public function __construct($file) {
        if (file_exists($file)) {
                $this->file = $file;
                $info = getimagesize($file);
                $this->info = array(
                    'width'  => $info[0],
                    'height' => $info[1],
                    'bits'   => $info['bits'],
                    'mime'   => $info['mime']
                );

            $this->image = $this->create($file);
        } else {
            trigger_error('Error: Could not load image ' . $file . '!');
        }
    }

    private function create($image) {
        $mime = $this->info['mime'];

        if ($mime == 'image/gif') {
            return imagecreatefromgif($image);
        } elseif ($mime == 'image/png') {
            return imagecreatefrompng($image);
        } elseif ($mime == 'image/jpeg') {
            return imagecreatefromjpeg($image);
        }
    }

    public function save($file="", $quality = 100, $ext=null) {
        if(is_null($ext)) {
            switch ($this->info['mime']) {
                case 'image/jpeg':
                case 'image/jpg':
                    imagejpeg($this->image, $file, $quality);
                break;
                case 'image/png':
                case 'image/x-png':
                    imagepng($this->image, $file, $quality);
                break;
                case 'image/gif':
                    imagegif($this->image, $file);
                break;
            }
        } else {
            switch ($ext) {
                case 'jpeg':
                case 'jpg':
                    imagejpeg($this->image, $file, $quality);
                break;
                case 'png':
                    imagepng($this->image, $file, $quality);
                break;
                case 'gif':
                    imagegif($this->image, $file);
                break;
            }
        }

        imagedestroy($this->image);
    }

    public function resize($width = 0, $height = 0) {
        if (!$this->info['width'] || !$this->info['height']) {
             return;
        }

        $image_old = $this->image;
        $this->image = imagecreatetruecolor($width, $height);
        $background = imagecolorallocate($this->image, 255, 255, 255);

        imagefilledrectangle($this->image, 0, 0, $width, $height, $background);
        imagecopyresampled($this->image, $image_old, 0, 0, 0, 0, $width, $height, $this->info['width'], $this->info['height']);
        imagedestroy($image_old);

        $this->info['width']  = $width;
        $this->info['height'] = $height;
    }

    public function resizeByPercent($percent=100) {
        $percent = floor($percent / 100);
        $width = floor($this->info['width'] * $percent);
        $height = floor($this->info['height'] * $percent);
        $this->resize($width, $height);
    }

    public function resizeByWidth($width=0) {
        $this->resize($width, $this->getHeightSizeByWidth($width));
    }

    public function resizeByHeight($height=0) {
        $this->resize($this->getWidthByHeight($height), $height);
    }

    public function getHeightSizeByWidth($width=0) {
        $ratio = floatval($this->info['width'] / $width);
        return floor($this->info['height'] / $ratio);
    }

    public function getWidthByHeight($height=0) {
        $ratio = floatval($this->info['height'] / $height);
        return floor($this->info['width'] / $ratio);
    }

    public function watermark($file, $position = 'bottomright') {
        $watermark = $this->create($file);

        $watermark_width = imagesx($watermark);
        $watermark_height = imagesy($watermark);

        switch($position) {
            case 'topleft':
                $watermark_pos_x = 0;
                $watermark_pos_y = 0;
                break;
            case 'topright':
                $watermark_pos_x = $this->info['width'] - $watermark_width;
                $watermark_pos_y = 0;
                break;
            case 'bottomleft':
                $watermark_pos_x = 0;
                $watermark_pos_y = $this->info['height'] - $watermark_height;
                break;
            case 'bottomright':
                $watermark_pos_x = $this->info['width'] - $watermark_width;
                $watermark_pos_y = $this->info['height'] - $watermark_height;
                break;
        }

        imagecopy($this->image, $watermark, $watermark_pos_x, $watermark_pos_y, 0, 0, 120, 40);
        imagedestroy($watermark);
    }

    public function crop($top_x, $top_y, $bottom_x, $bottom_y) {
        $image_old = $this->image;
        $this->image = imagecreatetruecolor($bottom_x - $top_x, $bottom_y - $top_y);

        $this->info['width'] = $bottom_x - $top_x;
        $this->info['height'] = $bottom_y - $top_y;

        imagecopy($this->image, $image_old, 0, 0, $top_x, $top_y, $this->info['width'], $this->info['height']);
        imagedestroy($image_old);
    }

    public function rotate($degree, $color = 'FFFFFF') {
        $rgb = $this->html2rgb($color);

        $this->image = imagerotate($this->image, $degree, imagecolorallocate($this->image, $rgb[0], $rgb[1], $rgb[2]));
        $this->info['width'] = imagesx($this->image);
        $this->info['height'] = imagesy($this->image);
    }

    public function getInfo() {
        return $this->info;
    }

    private function filter($filter) {
        imagefilter($this->image, $filter);
    }

    private function text($text, $x = 0, $y = 0, $size = 5, $color = '000000') {
        $rgb = $this->html2rgb($color);
        imagestring($this->image, $size, $x, $y, $text, imagecolorallocate($this->image, $rgb[0], $rgb[1], $rgb[2]));
    }

    private function merge($file, $x = 0, $y = 0, $opacity = 100) {
        $merge = $this->create($file);

        $merge_width = imagesx($image);
        $merge_height = imagesy($image);

        imagecopymerge($this->image, $merge, $x, $y, 0, 0, $merge_width, $merge_height, $opacity);
    }

    private function html2rgb($color) {
        if ($color[0] == '#') {
            $color = substr($color, 1);
        }

        if (strlen($color) == 6) {
            list($r, $g, $b) = array($color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5]);
        } elseif (strlen($color) == 3) {
            list($r, $g, $b) = array($color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2]);
        } else {
            return FALSE;
        }

        $r = hexdec($r);
        $g = hexdec($g);
        $b = hexdec($b);

        return array($r, $g, $b);
    }
}

function create_thumbnail($file, $width=0, $height=0, $folder='', $relativeTo='', $forcereplace=false, $stream=false) {
    if(!file_exists($file)) {
        trigger_error("image file not found");
        exit;
    }

    if($width<0) {
        $width=0;
    }

    if($height<0) {
        $height=0;
    }

    if($width==0 && $height==0) {
        trigger_error("image size must be defined");
        exit;
    }

    if(!is_dir($folder)) {
        trigger_error("folder $folder doesn't exists found");
        exit;
    }

    if(!is_dir($folder)) {
        trigger_error("thumbnail folder '".$folder."' not found");
        exit;
    }

    if(empty($relativeTo)) {
        $relativeTo = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR;
    }

    $info = pathinfo($file);

    $img = new Image($file);

    if(!!$width && !!$height) {

        $img->resize($width, $height);

    } else {

        if($width!=0) {
            $img->resizeByWidth($width);
        } elseif($height!=0) {
            $img->resizeByHeight($height);
        }

    }

    $fileinfo = $img->getInfo();

    if(!!$stream) {
        header("content-type: ".$fileinfo['mime']);
        $img->save();
        return;
    }
    
    $newfile = $folder . $info['filename'] . "-" . $fileinfo['width'] . "x" . $fileinfo['height'] . "." . $info['extension'];

    if(!file_exists($newfile) || !!$forcereplace) {
        $img->save($newfile);
    }

    return str_replace($relativeTo, "", $newfile);
}

function create_cropped_thumbnail($file, $resizeTo=0, $folder='', $relativeTo='', $forcereplace=true) {
    
    $info = getimagesize($file);

    if($resizeTo<0) {
        $resizeTo=0;
    }
    
    if($info[0] > $info[1]) {
        $thumb = create_thumbnail($file, 0, $resizeTo, $folder, $relativeTo, $forcereplace);
        $realthumb = getImgPath() . "user/avatar/" . $thumb;
        $info = getimagesize($realthumb);
        $top_x = floor($info[0]/2) - floor($resizeTo/2);
        $top_y = 0;
        $bottom_x = $top_x + $resizeTo;
        $bottom_y = $top_y + $resizeTo;
    } else {
        $thumb = create_thumbnail($file, $resizeTo, 0, $folder, $relativeTo, $forcereplace);
        $realthumb = getImgPath() . "user/avatar/" . $thumb;
        $info = getimagesize($realthumb);
        $top_x = 0;
        $top_y = floor($info[0]/2) - floor($resizeTo/2);
        $bottom_x = $top_x + $resizeTo;
        $bottom_y = $top_y + $resizeTo;
    }

    $realthumb = getImgPath() . "user/avatar/" . $thumb;
    $img = new Image($realthumb);

    $img->crop($top_x, $top_y, $bottom_x, $bottom_y);
    $img->save($realthumb);

    return $thumb;
}

?>